#pragma once
#include <iostream>
#include <unordered_map>
#include <vector>
#include <fstream>

#include "../comm/logger.hpp"
#include "../comm/util.hpp"

namespace ns_model{
    struct Question{
        std::string number;//题目编号
        std::string title;//题目的标题
        std::string star;//题目的难度
        int cpu_limit;//题目的时间要求
        int mem_limit;//题目的空间要求
        std::string desc;//题目的描述
        std::string header;//题目预设给用户在线编辑器的代码
        std::string tail;//题目的测试用例，需要和header拼接，形成完整代码
    };
    const std::string questions_list = "./questions/questions.list";
    const std::string questions_path = "./questions/";

    class Model{
    private:
        std::unordered_map<std::string,Question> questions;
    public:
        Model(){}
        ~Model(){}
    public:
        bool LoadQuestionList(const std::string& question_list){
            std::ifstream in(questions_list);
            std::string tmp_info;
            if(!in.is_open()){
                DLOG("打开题库文件失败,无法获取题库基本信息");
                return false;
            }
            while(std::getline(in,tmp_info)){
                std::vector<std::string> tmp_qinfo;
                Question q;
                helper::StringUtil::stringSpilt(tmp_info," ",tmp_qinfo); 
                if(tmp_qinfo.size() != 5){
                    DLOG("读取题目基本信息失败");
                    return false;
                }
                q.number = tmp_qinfo[0];
                q.title = tmp_qinfo[1];
                q.star = tmp_qinfo[2];
                q.cpu_limit = std::stoi(tmp_qinfo[3]);
                q.mem_limit = std::stoi(tmp_qinfo[4]);
                std::string path=questions_path;
                path += q.number;
                path += "/";

                bool ret;
                if(!helper::FileUtil::fileRead(path+"desc.txt",q.desc,true)){
                    DLOG("读取题目描述失败");
                    return false;
                }
                if(!helper::FileUtil::fileRead(path+"header.cpp",q.header,true)){
                    DLOG("读取预设文件时失败");
                    return false;
                }
                if(!helper::FileUtil::fileRead(path+"tail.cpp",q.title)){
                    DLOG("读取测试用例时失败");
                    return false;
                }

                questions.insert(std::make_pair(q.number,q));
                tmp_info.clear();
            }
            ILOG("加载题库成功");
            in.close();
            return true;
        }
        bool getAllQuestions(std::vector<Question> *out){
            if(!questions.empty()){
               DLOG("当前题目列表中没有任何题目");
               return false;
            }
            for(auto& x: questions){
                (*out).push_back(x.second);
            }
            ILOG("获取所有题目成功");
            return true;
        }
        bool getOneQuestion(const std::string& number,Question* q){
            if(!questions.empty()){
                DLOG("当前题目列表中没有任何题目");
                return false;
             }
             auto it = questions.find(number);
             if( it == questions.end() ){
                DLOG("指定的题目不存在");
                return false;
             }
             (*q) = it->second;
        }
    };
}
